// 用来访问 node 内置url模块
import { fileURLToPath, URL } from "node:url";

import { defineConfig, loadEnv, UserConfig } from "vite";

import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";

// 时间处理工具
import dayjs from "dayjs";
// 路径
import path from "path";
// 一个现代JavaScript实用程序库，提供模块化、性能和附加功能
import loaded from "lodash";

// 注入导入插件
// import inject from "@rollup/plugin-inject";
// rollup.config.js 配置
// import resolve from "@rollup/plugin-node-resolve";

// html注入插件
import { createHtmlPlugin } from "vite-plugin-html";
// px转换rem插件
import postcssPluginPx2rem from "postcss-plugin-px2rem";
// 自动添加css 前缀解决不同的浏览器的兼容问题
import autoprefixer from 'autoprefixer'


// 项目包配置
import { appInfo } from "./package.json";

// 代理配置
import proxyConfig from "./build/proxy";

// 路径解析
function pathResolve(dir: string): string {
    return path.resolve(__dirname, dir);
}

// 环境变量目录
const envDir = path.join(process.cwd(), "./envConfig");

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
    // 根据当前工作目录中的 `mode` 加载 .env 文件
    // 设置第三个参数为 '' 来加载所有环境变量，而不管是否有 `VITE_` 前缀。
    // 加载环境变量文件，包含 process.env
    const envInfo = /*process.env || */ loadEnv(mode, envDir, "");

    // 基础配置
    const baseConfig = {
        // 环境变量目录
        envDir,
        // 公共基础路径(正常情况不建议修改)
        base: envInfo.APP_BASE,
        // 以 envPrefix 开头的环境变量会通过 import.meta.env 暴露在你的客户端源码中。
        envPrefix: ["VITE_", "APP_"],
        // 插件
        plugins: [
            vue(),
            vueJsx(),
            // 设置全局模块别名 (配合TS成了鸡肋)
            // inject({
            //     // 环境变量
            //     // $env: ["@model/app.model/env", "*"],
            //     // 路由对象
            //     // $router: ["@model/app.model/router", "default"],
            //     /************************************* 插件 *********************************************/
            //     // 服务请求处理
            //     // $service: ["@plugins/service", "default"],
            //     /************************************* model *********************************************/
            //     // 应用模块
            //     // $applicationModel: ["@model/application.model", "default"],
            // }),
            // HTML 压缩能力、 EJS 模版能力、多页应用支持、支持自定义entry、支持自定义template
            // https://github.com/vbenjs/vite-plugin-html/blob/main/README.zh_CN.md
            createHtmlPlugin({
                minify: true,
                /**
                 * 在这里写entry后，你将不需要在`index.html`内添加 script 标签，原有标签需要删除
                 * @default src/main.ts
                 */
                entry: 'src/main.ts',
                /**
                 * 如果你想将 `index.html`存放在指定文件夹，可以修改它，否则不需要配置
                 * @default index.html
                 */
                template: 'index.html',

                /**
                 * 需要注入 index.html ejs 模版的数据
                 */
                inject: {
                    data: {
                        // 站点名称
                        name: appInfo.name,
                        // 站点标题
                        title: appInfo.title,
                        // 站点描述
                        description: appInfo.description,
                        // 站点关键词
                        keywords: Array.isArray(appInfo.keywords) ? appInfo.keywords.join(',') : appInfo.keywords,
                    },
                    tags: [
                        // 在body中注入 div id为app的标签
                        {
                            injectTo: 'body-prepend',
                            tag: 'div',
                            attrs: {
                                id: 'app',
                            },
                        },
                    ],
                },
            }),
        ],
        preview: {
            port: 8083,
        },
        // Resolve 配置如何寻找模块所对应的文件
        resolve: {
            // 路径别名
            alias: {
                '@': fileURLToPath(new URL('./src', import.meta.url)),
                "@public": pathResolve("./public"),
                "@page": pathResolve("./src/page"),
                "@comm": pathResolve("./src/comm"),
                "@model": pathResolve("./src/model"),
                "@assets": pathResolve("./src/assets"),
                "@config": pathResolve("./src/config"),
                "@utils": pathResolve("./src/extend/utils"),
                "@plugins": pathResolve("./src/extend/plugins"),
                "@directive": pathResolve("./src/extend/directive"),
                "@components": pathResolve("./src/extend/components"),
            },
        },
        // 全局变量定义
        define: {
            // command 命令
            __COMMAND__: `'${command}'`,
            // 环境模式
            __Env_Mode__: `'${mode}'`,
            // 应用名称
            __APP_Name__: `'${appInfo.name}'`,
            // 应用版本
            __APP_Version__: `'${appInfo.version}'`,
            // 应用小版本
            __APP_Little_Version__: `'${dayjs().format("YYYY.MM.DD.HHmm.a")}'`,
            // 设计图尺寸，单位为px
            __APP_DesignWidth__: Number(envInfo.APP_DesignWidth),
        },
        build: {
            outDir: 'dist',
        },
        css: {
            postcss: {
                plugins: [
                    // 自动添加前缀 的浏览器
                    autoprefixer({
                        overrideBrowserslist: [
                            "Android 4.1",
                            "iOS 7.1",
                            "Chrome > 31",
                            "ie >= 8"
                            //'last 2 versions', // 所有主流浏览器最近2个版本
                        ],
                        grid: true
                    }),
                    // px转换rem插件
                    postcssPluginPx2rem({
                        rootValue: 14,  // 换算基数
                        unitPrecision: 5, //允许REM单位增长到的十进制数字，其实就是精度控制
                        // propWhiteList: [], // 默认值是一个空数组，这意味着禁用白名单并启用所有属性。
                        // propBlackList: [], // 黑名单
                        exclude: /(node_module)/, //默认false，可以（reg）利用正则表达式排除某些文件夹的方法，例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem，请把此属性设为默认值
                        selectorBlackList: ['vant', 'mu'], // 忽略转换正则匹配项并保留为px的选择器
                        // ignoreIdentifier: false, //（boolean/string）忽略单个属性的方法，启用ignoreidentifier后，replace将自动设置为true。
                        // replace: true, // （布尔值）替换包含REM的规则，而不是添加回退。
                        mediaQuery: false, //（布尔值）允许在媒体查询中转换px
                        minPixelValue: 0  //设置要替换的最小像素值(3px会被转rem)。 默认 0
                    })
                ]
            },
            preprocessorOptions: {
                less: {
                    charset: false,
                    additionalData: '@import "./src/assets/style/global.less";'
                }
            }
        }
    };

    // 扩展自定义配置
    const customConfig: UserConfig = {};

    // 命令检查
    if (command === "serve") {
        // 常用于开发模式下应用服务
        customConfig.server = {
            // 开发模式访问的端口
            port: 3030,
            host: true,
            // https: true,
            open: true,
            fs: {
                strict: true,
            },
            hmr: {
                overlay: false,
            },
            // 常用于接口代理
            proxy: proxyConfig,
        };

    } else if (command === "build") {
        // build 配置
        customConfig.build = {
            // 是否开启sourceMap
            sourcemap: true,
            // 在 outDir 中生成 manifest.json
            manifest: true,
        };
    }

    // 启动模式检查
    switch (mode) {
        // 开发模式
        case "develop":
            break;
        // 测试模式
        case "testing":
            break;
        // 生产模式
        case "production":
            break;
    }

    // 配置合并
    return loaded.merge(baseConfig, customConfig);
});
